﻿using FNN.Networks;
using FNN.SourcePoints;
using Sparrow.Chart;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;

namespace FNNClientApplication
{
    /// <summary>
    /// Логика взаимодействия для ChartingWindow.xaml
    /// </summary>
    public partial class NetworkActivityWindow : Window
    {
        private int _pointsCount = 250;
        private double _initialFunds = 100000.0;

        public NetworkActivityWindow()
        {
            InitializeComponent();
        }

        protected void PopulateSummary(FinancialNetwork target, IEnumerable<DateSourcePoint> dataSource)
        {
            var profitPercent = ((target.Funds - _initialFunds) / _initialFunds * 100).ToString("F2");
            LblNetworkOperationCount.Content = target.Transactions.Count;
            LblNetworkOperationCountTitle.Content = "Количество транзакций:";
            LblNetworkResultsPercent.Content = profitPercent + "%";
            LblNetworkResultsPercentTitle.Content = "Прибыльность:";
            LblNetworkResults.Content = target.Funds.ToString("F2");
            LblNetworkResultsTitle.Content = "Капитал сети:";
        }

        public void ShowNetworkActivity(FinancialNetwork target, IEnumerable<DateSourcePoint> dataSource)
        {
            LblNetworkName.Content = target.NetworkName;
            PopulateSummary(target, dataSource);

            Dictionary<DateTime, double> dataSourceDictionary = new Dictionary<DateTime, double>();
            Dictionary<DateTime, double> buyingDictionary = new Dictionary<DateTime, double>();
            Dictionary<DateTime, double> sellingDictionary = new Dictionary<DateTime, double>();

            var minimumDate = (target.Transactions.Count > 0) ? target.Transactions.Min(o => o.TransactionDate).AddDays(-7) : dataSource.Min(o => o.PointDate);
            var maximumDate = (target.Transactions.Count > 0) ? target.Transactions.Max(o => o.TransactionDate).AddDays(7) : dataSource.Max(o => o.PointDate);
            var filteredDataSource = dataSource.Where(o => o.PointDate <= maximumDate && o.PointDate >= minimumDate).ToList();
            int neededIndexes = filteredDataSource.Count() / _pointsCount;

            foreach (var point in filteredDataSource)
            {
                var pointIndex = filteredDataSource.IndexOf(point);
                if ((pointIndex % neededIndexes) == 0) dataSourceDictionary.Add(point.PointDate, point.Coordinates.Values.ElementAt(0));
            }

            foreach (var transaction in target.Transactions)
            {
                if (transaction.TransactionType)
                {
                    sellingDictionary.Add(transaction.TransactionDate, dataSource.First(o => o.PointDate.Date == transaction.TransactionDate.Date).Coordinates.Values.ElementAt(0));
                }
                else
                {
                    buyingDictionary.Add(transaction.TransactionDate, dataSource.First(o => o.PointDate.Date == transaction.TransactionDate.Date).Coordinates.Values.ElementAt(0));
                }
            }

            PopulatePoints(SourceChart, dataSourceDictionary);
            SourceChart.Refresh();
            PopulatePoints(BuyingChart, buyingDictionary);
            BuyingChart.Refresh();
            PopulatePoints(SellingChart, sellingDictionary);
            SellingChart.Refresh();
        }

        protected void PopulatePoints(LineSeries targetSeries, Dictionary<DateTime, double> sourceDictionary)
        {
            targetSeries.Points.Clear();
            foreach (var pointSource in sourceDictionary)
            {
                targetSeries.Points.Add(new TimePoint() { Time = pointSource.Key, Value = pointSource.Value });
            }
        }

        protected void PopulatePoints(ScatterSeries targetSeries, Dictionary<DateTime, double> sourceDictionary)
        {
            targetSeries.Points.Clear();
            foreach (var pointSource in sourceDictionary)
            {
                targetSeries.Points.Add(new TimePoint() { Time = pointSource.Key, Value = pointSource.Value });
            }
        }
    }
}
